package com.ruoyi.common.utils.date;

import com.alibaba.fastjson.JSONObject;

import java.util.Date;
import java.util.concurrent.TimeUnit;

public class TimeDuration implements Comparable<TimeDuration> {
	private Date startDate = null;
	private Date endDate = null;

	public TimeDuration() {
	}

	public TimeDuration(Date startDate, Date endDate) {
		this.startDate = startDate;
		this.endDate = endDate;
	}

	public Date getStartDate() {
		return startDate;
	}

	public void setStartDate(Date startDate) {
		this.startDate = startDate;
	}

	public Date getEndDate() {
		return endDate;
	}

	public void setEndDate(Date endDate) {
		this.endDate = endDate;
	}

	public boolean isValidDuration() {
		boolean flag = (this.startDate != null && this.endDate != null && this.startDate.compareTo(this.endDate) <= 0);
		return flag;
	}

	/**
	 * 获取时段长度
	 * 
	 * @param timeUnit
	 *            时间单位
	 * @return
	 */
	public double getDuration(TimeUnit timeUnit) {
		if (this.startDate != null && this.endDate != null) {
			double result = TimeUtil.getDuration(this.startDate, this.endDate, timeUnit);
			return result;
		}
		return 0.0;
	}

	/**
	 * 判断时间段的起始时间是否与截止时间相同
	 * 
	 * @return
	 */
	public boolean zeroDuration() {
		if (this.startDate != null && this.endDate != null) {
			boolean zero = Long.valueOf(this.startDate.getTime() - this.endDate.getTime()) == 0;
			return zero;
		}
		return false;
	}

	/**
	 * 判断特定时间戳是否在当前时段内
	 * 
	 * @param timeMillis
	 *            时间戳
	 * @return
	 */
	public boolean inDuration(long timeMillis) {
		boolean flag = (this.startDate.getTime() <= timeMillis && timeMillis <= this.endDate.getTime());
		return flag;
	}

	/**
	 * 判断当前时段中是否只包含指定时段的起始时间点而不包含截止时间点
	 * 
	 * @param timeDuration
	 *            指定时段
	 * @return
	 */
	public boolean crossStart(TimeDuration timeDuration) {
		if (this.startDate != null && this.endDate != null && timeDuration.startDate != null
				&& timeDuration.endDate != null) {
			boolean contains = this.startDate.compareTo(timeDuration.startDate) <= 0
					&& this.endDate.compareTo(timeDuration.startDate) > 0
					&& this.endDate.compareTo(timeDuration.endDate) < 0;
			return contains;
		}
		return false;
	}

	/**
	 * 判断当前时段中是否只包含指定时段的截止时间点而不包含起始时间点
	 * 
	 * @param timeDuration
	 *            指定时段
	 * @return
	 */
	public boolean crossEnd(TimeDuration timeDuration) {
		if (this.startDate != null && this.endDate != null && timeDuration.startDate != null
				&& timeDuration.endDate != null) {
			boolean contains = this.startDate.compareTo(timeDuration.startDate) > 0
					&& this.startDate.compareTo(timeDuration.endDate) < 0
					&& this.endDate.compareTo(timeDuration.endDate) >= 0;
			return contains;
		}
		return false;
	}

	/**
	 * 判断当前时段是否包含 timeDuration时段
	 * 
	 * @param timeDuration
	 *            指定时段
	 * @return
	 */
	public boolean contains(TimeDuration timeDuration) {
		if (this.startDate != null && this.endDate != null && timeDuration.startDate != null
				&& timeDuration.endDate != null) {
			boolean contains = this.startDate.compareTo(timeDuration.startDate) <= 0
					&& this.endDate.compareTo(timeDuration.endDate) >= 0;
			return contains;
		}
		return false;
	}

	/**
	 * 判断当前时段是否以指定时段开始
	 * 
	 * @param timeDuration
	 *            指定时段
	 * @return
	 */
	public boolean containsStartWith(TimeDuration timeDuration) {
		if (this.contains(timeDuration)) {
			boolean flag = this.startDate.compareTo(timeDuration.startDate) == 0;
			return flag;
		}
		return false;
	}

	/**
	 * 判断当前时段是否以指定时段结束
	 * 
	 * @param timeDuration
	 *            指定时段
	 * @return
	 */
	public boolean containsEndWith(TimeDuration timeDuration) {
		if (this.contains(timeDuration)) {
			boolean flag = this.endDate.compareTo(timeDuration.endDate) == 0;
			return flag;
		}
		return false;
	}

	public boolean startDateLessThan(TimeDuration timeDuration) {
		if (this.startDate != null && timeDuration.startDate != null) {
			return this.startDate.compareTo(timeDuration.startDate) <= 0;
		}
		return false;
	}

	public boolean endDateMoreThan(TimeDuration timeDuration) {
		if (this.endDate != null && timeDuration.endDate != null) {
			return this.endDate.compareTo(timeDuration.endDate) > 0;
		}
		return false;
	}

	@Override
	public int hashCode() {
		int result = 0;
		if (this.startDate != null) {
			result += 11 * this.startDate.hashCode();
		}
		if (this.endDate != null) {
			result += 13 * this.endDate.hashCode();
		}
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (!(obj instanceof TimeDuration)) {
			return false;
		}
		if (this == obj) {
			return true;
		}
		return this.hashCode() == obj.hashCode();
	}

	@Override
	public int compareTo(TimeDuration other) {
		if (this.startDate != null && other.startDate != null) {
			return this.startDate.compareTo(other.startDate);
		}
		if (this.endDate != null && other.endDate != null) {
			return this.endDate.compareTo(other.endDate);
		}
		return 0;
	}

	@Override
	public String toString() {
		String startDateTime = TimeUtil.format(this.startDate);
		String endDateTime = TimeUtil.format(this.endDate);
		JSONObject jsonObj = new JSONObject();
		jsonObj.put("startDate", startDateTime);
		jsonObj.put("endDate", endDateTime);
		return jsonObj.toJSONString();
	}
}
